#ifndef THINK_THINK_COLLECTION_H
#define THINK_THINK_COLLECTION_H

static char* think_collection =
	"\n"
	"// +----------------------------------------------------------------------\n"
	"// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n"
	"// +----------------------------------------------------------------------\n"
	"// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.\n"
	"// +----------------------------------------------------------------------\n"
	"// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n"
	"// +----------------------------------------------------------------------\n"
	"// | Author: zhangyajun <448901948@qq.com>\n"
	"// +----------------------------------------------------------------------\n"
	"\n"
	"namespace think;\n"
	"\n"
	"use ArrayAccess;\n"
	"use ArrayIterator;\n"
	"use Countable;\n"
	"use IteratorAggregate;\n"
	"use JsonSerializable;\n"
	"\n"
	"class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable\n"
	"{\n"
	"    /**\n"
	"     * @var array 数据\n"
	"     */\n"
	"    protected $items = [];\n"
	"\n"
	"    /**\n"
	"     * Collection constructor.\n"
	"     * @access public\n"
	"     * @param  array $items 数据\n"
	"     */\n"
	"    public function __construct($items = [])\n"
	"    {\n"
	"        $this->items = $this->convertToArray($items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 创建 Collection 实例\n"
	"     * @access public\n"
	"     * @param  array $items 数据\n"
	"     * @return static\n"
	"     */\n"
	"    public static function make($items = [])\n"
	"    {\n"
	"        return new static($items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 判断数据是否为空\n"
	"     * @access public\n"
	"     * @return bool\n"
	"     */\n"
	"    public function isEmpty()\n"
	"    {\n"
	"        return empty($this->items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 将数据转成数组\n"
	"     * @access public\n"
	"     * @return array\n"
	"     */\n"
	"    public function toArray()\n"
	"    {\n"
	"        return array_map(function ($value) {\n"
	"            return ($value instanceof Model || $value instanceof self) ?\n"
	"                $value->toArray() :\n"
	"                $value;\n"
	"        }, $this->items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取全部的数据\n"
	"     * @access public\n"
	"     * @return array\n"
	"     */\n"
	"    public function all()\n"
	"    {\n"
	"        return $this->items;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 交换数组中的键和值\n"
	"     * @access public\n"
	"     * @return static\n"
	"     */\n"
	"    public function flip()\n"
	"    {\n"
	"        return new static(array_flip($this->items));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 返回数组中所有的键名组成的新 Collection 实例\n"
	"     * @access public\n"
	"     * @return static\n"
	"     */\n"
	"    public function keys()\n"
	"    {\n"
	"        return new static(array_keys($this->items));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 返回数组中所有的值组成的新 Collection 实例\n"
	"     * @access public\n"
	"     * @return static\n"
	"     */\n"
	"    public function values()\n"
	"    {\n"
	"        return new static(array_values($this->items));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 合并数组并返回一个新的 Collection 实例\n"
	"     * @access public\n"
	"     * @param  mixed $items 新的数据\n"
	"     * @return static\n"
	"     */\n"
	"    public function merge($items)\n"
	"    {\n"
	"        return new static(array_merge($this->items, $this->convertToArray($items)));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 比较数组，返回差集生成的新 Collection 实例\n"
	"     * @access public\n"
	"     * @param  mixed $items 做比较的数据\n"
	"     * @return static\n"
	"     */\n"
	"    public function diff($items)\n"
	"    {\n"
	"        return new static(array_diff($this->items, $this->convertToArray($items)));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 比较数组，返回交集组成的 Collection 新实例\n"
	"     * @access public\n"
	"     * @param  mixed $items 比较数据\n"
	"     * @return static\n"
	"     */\n"
	"    public function intersect($items)\n"
	"    {\n"
	"        return new static(array_intersect($this->items, $this->convertToArray($items)));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 返回并删除数据中的的最后一个元素（出栈）\n"
	"     * @access public\n"
	"     * @return mixed\n"
	"     */\n"
	"    public function pop()\n"
	"    {\n"
	"        return array_pop($this->items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 返回并删除数据中首个元素\n"
	"     * @access public\n"
	"     * @return mixed\n"
	"     */\n"
	"    public function shift()\n"
	"    {\n"
	"        return array_shift($this->items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 在数组开头插入一个元素\n"
	"     * @access public\n"
	"     * @param mixed $value 值\n"
	"     * @param mixed $key   键名\n"
	"     * @return void\n"
	"     */\n"
	"    public function unshift($value, $key = null)\n"
	"    {\n"
	"        if (is_null($key)) {\n"
	"            array_unshift($this->items, $value);\n"
	"        } else {\n"
	"            $this->items = [$key => $value] + $this->items;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 在数组结尾插入一个元素\n"
	"     * @access public\n"
	"     * @param  mixed $value 值\n"
	"     * @param  mixed $key   键名\n"
	"     * @return void\n"
	"     */\n"
	"    public function push($value, $key = null)\n"
	"    {\n"
	"        if (is_null($key)) {\n"
	"            $this->items[] = $value;\n"
	"        } else {\n"
	"            $this->items[$key] = $value;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 通过使用用户自定义函数，以字符串返回数组\n"
	"     * @access public\n"
	"     * @param  callable $callback 回调函数\n"
	"     * @param  mixed    $initial  初始值\n"
	"     * @return mixed\n"
	"     */\n"
	"    public function reduce(callable $callback, $initial = null)\n"
	"    {\n"
	"        return array_reduce($this->items, $callback, $initial);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 以相反的顺序创建一个新的 Collection 实例\n"
	"     * @access public\n"
	"     * @return static\n"
	"     */\n"
	"    public function reverse()\n"
	"    {\n"
	"        return new static(array_reverse($this->items));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 把数据分割为新的数组块\n"
	"     * @access public\n"
	"     * @param  int  $size         分隔长度\n"
	"     * @param  bool $preserveKeys 是否保持原数据索引\n"
	"     * @return static\n"
	"     */\n"
	"    public function chunk($size, $preserveKeys = false)\n"
	"    {\n"
	"        $chunks = [];\n"
	"\n"
	"        foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) {\n"
	"            $chunks[] = new static($chunk);\n"
	"        }\n"
	"\n"
	"        return new static($chunks);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 给数据中的每个元素执行回调\n"
	"     * @access public\n"
	"     * @param  callable $callback 回调函数\n"
	"     * @return $this\n"
	"     */\n"
	"    public function each(callable $callback)\n"
	"    {\n"
	"        foreach ($this->items as $key => $item) {\n"
	"            $result = $callback($item, $key);\n"
	"\n"
	"            if (false === $result) {\n"
	"                break;\n"
	"            }\n"
	"\n"
	"            if (!is_object($item)) {\n"
	"                $this->items[$key] = $result;\n"
	"            }\n"
	"        }\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 用回调函数过滤数据中的元素\n"
	"     * @access public\n"
	"     * @param callable|null $callback 回调函数\n"
	"     * @return static\n"
	"     */\n"
	"    public function filter(callable $callback = null)\n"
	"    {\n"
	"        return new static(array_filter($this->items, $callback ?: null));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 返回数据中指定的一列\n"
	"     * @access public\n"
	"     * @param mixed $columnKey 键名\n"
	"     * @param null  $indexKey  作为索引值的列\n"
	"     * @return array\n"
	"     */\n"
	"    public function column($columnKey, $indexKey = null)\n"
	"    {\n"
	"        if (function_exists(\'array_column\')) {\n"
	"            return array_column($this->items, $columnKey, $indexKey);\n"
	"        }\n"
	"\n"
	"        $result = [];\n"
	"        foreach ($this->items as $row) {\n"
	"            $key    = $value = null;\n"
	"            $keySet = $valueSet = false;\n"
	"\n"
	"            if (null !== $indexKey && array_key_exists($indexKey, $row)) {\n"
	"                $key    = (string) $row[$indexKey];\n"
	"                $keySet = true;\n"
	"            }\n"
	"\n"
	"            if (null === $columnKey) {\n"
	"                $valueSet = true;\n"
	"                $value    = $row;\n"
	"            } elseif (is_array($row) && array_key_exists($columnKey, $row)) {\n"
	"                $valueSet = true;\n"
	"                $value    = $row[$columnKey];\n"
	"            }\n"
	"\n"
	"            if ($valueSet) {\n"
	"                if ($keySet) {\n"
	"                    $result[$key] = $value;\n"
	"                } else {\n"
	"                    $result[] = $value;\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        return $result;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 对数据排序，并返回排序后的数据组成的新 Collection 实例\n"
	"     * @access public\n"
	"     * @param  callable|null $callback 回调函数\n"
	"     * @return static\n"
	"     */\n"
	"    public function sort(callable $callback = null)\n"
	"    {\n"
	"        $items    = $this->items;\n"
	"        $callback = $callback ?: function ($a, $b) {\n"
	"            return $a == $b ? 0 : (($a < $b) ? -1 : 1);\n"
	"        };\n"
	"\n"
	"        uasort($items, $callback);\n"
	"        return new static($items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 将数据打乱后组成新的 Collection 实例\n"
	"     * @access public\n"
	"     * @return static\n"
	"     */\n"
	"    public function shuffle()\n"
	"    {\n"
	"        $items = $this->items;\n"
	"\n"
	"        shuffle($items);\n"
	"        return new static($items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 截取数据并返回新的 Collection 实例\n"
	"     * @access public\n"
	"     * @param  int  $offset       起始位置\n"
	"     * @param  int  $length       截取长度\n"
	"     * @param  bool $preserveKeys 是否保持原先的键名\n"
	"     * @return static\n"
	"     */\n"
	"    public function slice($offset, $length = null, $preserveKeys = false)\n"
	"    {\n"
	"        return new static(array_slice($this->items, $offset, $length, $preserveKeys));\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 指定的键是否存在\n"
	"     * @access public\n"
	"     * @param  mixed $offset 键名\n"
	"     * @return bool\n"
	"     */\n"
	"    public function offsetExists($offset)\n"
	"    {\n"
	"        return array_key_exists($offset, $this->items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取指定键对应的值\n"
	"     * @access public\n"
	"     * @param  mixed $offset 键名\n"
	"     * @return mixed\n"
	"     */\n"
	"    public function offsetGet($offset)\n"
	"    {\n"
	"        return $this->items[$offset];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置键值\n"
	"     * @access public\n"
	"     * @param  mixed $offset 键名\n"
	"     * @param  mixed $value  值\n"
	"     * @return void\n"
	"     */\n"
	"    public function offsetSet($offset, $value)\n"
	"    {\n"
	"        if (is_null($offset)) {\n"
	"            $this->items[] = $value;\n"
	"        } else {\n"
	"            $this->items[$offset] = $value;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 删除指定键值\n"
	"     * @access public\n"
	"     * @param  mixed $offset 键名\n"
	"     * @return void\n"
	"     */\n"
	"    public function offsetUnset($offset)\n"
	"    {\n"
	"        unset($this->items[$offset]);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 统计数据的个数\n"
	"     * @access public\n"
	"     * @return int\n"
	"     */\n"
	"    public function count()\n"
	"    {\n"
	"        return count($this->items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取数据的迭代器\n"
	"     * @access public\n"
	"     * @return ArrayIterator\n"
	"     */\n"
	"    public function getIterator()\n"
	"    {\n"
	"        return new ArrayIterator($this->items);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 将数据反序列化成数组\n"
	"     * @access public\n"
	"     * @return array\n"
	"     */\n"
	"    public function jsonSerialize()\n"
	"    {\n"
	"        return $this->toArray();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 转换当前数据集为 JSON 字符串\n"
	"     * @access public\n"
	"     * @param  integer $options json 参数\n"
	"     * @return string\n"
	"     */\n"
	"    public function toJson($options = JSON_UNESCAPED_UNICODE)\n"
	"    {\n"
	"        return json_encode($this->toArray(), $options);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 将数据转换成字符串\n"
	"     * @access public\n"
	"     * @return string\n"
	"     */\n"
	"    public function __toString()\n"
	"    {\n"
	"        return $this->toJson();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 将数据转换成数组\n"
	"     * @access protected\n"
	"     * @param  mixed $items 数据\n"
	"     * @return array\n"
	"     */\n"
	"    protected function convertToArray($items)\n"
	"    {\n"
	"        return $items instanceof self ? $items->all() : (array) $items;\n"
	"    }\n"
	"}\n"
	"\n"
;
#endif